﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Aragorn.SOA.Infratructure.Config;
using Aragorn.SOA.Infratructure.Interface;
using Aragorn.SOA.Utility;
using ZooKeeperNet;
using Newtonsoft.Json;

namespace Aragorn.SOA.Infratructure
{
    public class ServicesProxy : IProxy
    {
        protected IZooKeeper zk;
        ZKConfig config = new ZKConfig();
        private string registryAddress;

        private ServicesWatcher serviceswatcher;

        //zookeeper服务器地址
        public void ServiceRegistry(String registryAddress)
        {
            this.registryAddress = registryAddress;
        }


        public void Register(ServicesMeta service)
        {   
            var zkhelper = ZkHelper.GetInstance();


            zk = zkhelper.ConnectServer(config.Host, new TimeSpan(1, 0, 0), null);
            //zkhelper.Execute(() =>
            //{
            //var zk = new ZooKeeper("192.168.1.126:2181", new TimeSpan(1, 0, 0), null);
            //Thread.Sleep(1000);
            //if (zk.State == ZooKeeper.States.CONNECTED)
            //{
            var path = config.ZK_REGISTRY_PATH;  //@data/services
            var s = @path + "/" + service.type;

            //注册自身服务类别节点
            if (zk.Exists(path + "/" + service.type, false) == null)

                zk.Create(s, service.Description.GetBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.Persistent);

            serviceswatcher = new ServicesWatcher(zk);

            //注册watcher
            zk.Exists(path + "/" + service.type, serviceswatcher);

            //var sl = @path + "/" + service.Category + "/" + service.ServicesName.Substring(0, service.ServicesName.Length - 1);
            //注册服务类别下的服务名节点
            if (zk.Exists(path + "/" + service.type + "/" + service.ServicesName, false) == null)
            {
                zk.Create(path + "/" + service.type + "/" + service.ServicesName,
                  JsonConvert.SerializeObject(service).GetBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.Persistent);
            }


            //实现leader模式
            //1.注册服务节点
            //首先创建一个 Persistent 目录节点，例如“ /election ”。然后。每一个 ZooKeeper 服务器在此目录下创建一个 SEQUENCE| EPHEMERAL 类型的节点，例如“ /election/n_ ”。在 SEQUENCE 标志下， ZooKeeper 将自动地为每一个 ZooKeeper 服务器分配一个比前一个分配的序号要大的序号。此时创建节点的 ZooKeeper 服务器中拥有最小序号编号的服务器将成为 Leader 。
            //if (zk.Exists(path + "/" + service.Category + "/" + service.ServicesName+"/Provider",false)==null)
            //{
            //    zk.Create(path + "/" + service.Category + "/" + service.ServicesName + "/Provider",
            //        "服务提供的集群地址".GetBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.Persistent);
            //}

            var servicesaddress = new ServicesWatcher(zk);

            //注册watcher
            zk.Exists(path + "/" + service.type + "/" + service.ServicesName,
                servicesaddress);

            //2.服务地址枚举,注册临时节点,Ephemeral类型
            if (zk.Exists(path + "/" + service.type + "/" + service.ServicesName + "/" + service.Address, false) == null)
            {
                zk.Create(
                        path + "/" + service.type + "/" + service.ServicesName + "/" + service.Address,
                        service.Description.GetBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.Ephemeral);
            }
            //}

            //zk.Dispose();
            //});
        }

        public void Start()
        {

        }


        //delete服务
        public void Stop()
        {
            try
            {
                zk.Dispose();
            }
            catch (Exception)
            {

                throw;
            }
        }


        public virtual void Watcher()
        {

        }
    }
}
